package redisclient;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;

public class RedisConnection {

    private static Logger logger = LoggerFactory.getLogger(RedisConnection.class);

    final Selector selector;
    final SelectionKey selectionKey;
    final SocketChannel socketChannel;

    Command pendingsendCommand;
    Command sentedCommand;

    public RedisConnection(Selector selector, SelectionKey selectionKey, SocketChannel socketChannel) {
        this.selector = selector;
        this.selectionKey = selectionKey;
        this.socketChannel = socketChannel;
    }

    public void executeCommand(GetCommand command) {
        this.pendingsendCommand = command;
        this.selectionKey.interestOps(this.selectionKey.interestOps() | SelectionKey.OP_WRITE);
        selector.wakeup();
    }


    public String get(String k) {
        GetCommand getCommand = new GetCommand(k);
        executeCommand(getCommand);

        return getCommand.get();
    }

    public void write() {
        try {
            if (this.pendingsendCommand != null) {
                ByteBuffer byteBuffer = this.pendingsendCommand.toByteBuffer();
                logger.info("channel write data");
                socketChannel.write(byteBuffer);

                this.sentedCommand = this.pendingsendCommand;
                this.pendingsendCommand = null;

                this.selectionKey.interestOps(this.selectionKey.interestOps() & ~SelectionKey.OP_WRITE);
            }
        } catch (IOException e) {
            throw new RedisException(e);
        }
    }

    public void read() throws IOException {
        try {
            logger.info("channel read data");
            this.sentedCommand.read(socketChannel);
        } catch (IOException e) {
            throw new RedisException(e);
        }
    }

}
